package com.ecp.commons.service;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.stereotype.Repository;

import com.ecp.commons.bean.Region;
import com.ecp.commons.db.GenericServiceImpl;

@Repository("regionService")
public class RegionServiceImpl extends GenericServiceImpl<Region> implements RegionService {

	@Override
	public int addRegion(Region region) throws Exception {
		// setId
		region.setId(this.generateId());

		// setPath
		this.genAndsetPath(region);

		// add
		this.add(region);

		return region.getId();
	}

	@Override
	public int save(Region region) throws Exception {
		if (region.getId() == 0) {
			region.setId(this.generateId());
			this.genAndsetPath(region);
			this.add(region);
		} else {
			this.genAndsetPath(region);
			this.update(region);
		}
		return region.getId();
	}

	private String genPath(int id, int parentId) throws Exception {
		// setPath
		StringBuffer path = new StringBuffer();
		if (parentId != 0) {
			Region parentRegion = this.load(parentId);
			if (parentRegion == null) {
				throw new Exception("parent region(" + parentId + ") is not exist!");
			}
			path.append(parentRegion.getPath());
		} else {
			path.append("/");
		}
		path.append(id).append("/");
		return path.toString();
	}

	private void genAndsetPath(Region region) throws Exception {
		region.setPath(this.genPath(region.getId(), region.getParentId()));
	}

	@Override
	public int deleteRegions(int[] ids) throws Exception {
		if (ids.length == 0) {
			return 0;
		}
		StringBuilder sql = new StringBuilder();
		sql.append("delete from region where id in (");
		for (int i : ids) {
			sql.append(i).append(",");
		}
		sql.setLength(sql.length() - 1);
		sql.append(");");
		return this.execute(sql.toString(), new Object[] {});
	}

	@Override
	public List<Region> getChildren(int id) throws Exception {
		String sql = "SELECT * FROM region WHERE parentId=? ORDER BY displayOrder, id";
		return this.getEntityList(sql, new Object[] { id });
	}

	@Override
	public boolean isSubregion(int id, int subId) throws Exception {
		boolean res = false;
		Region region = this.load(id);
		if (region != null) {
			res = (region.getPath().indexOf("/" + subId + "/") >= 0);
		}
		return res;
	}

	@Override
	public String getFullPathIdString(int id, String px) throws Exception {
		StringBuilder sb = new StringBuilder();
		Region region = this.load(id);
		if (region != null) {
			for (Integer i : region.getPathIds()) {
				if (i != 0) {
					sb.append(i).append(px);
				}
			}
			if (sb.length() > 0) {
				sb.setLength(sb.length() - px.length());
			}
		}
		return sb.toString();
	}

	@Override
	public String getFullPathString(int id, String px) throws Exception {
		StringBuilder sb = new StringBuilder();
		Region region = this.load(id);
		if (region != null) {
			for (Integer i : region.getPathIds()) {
				Region r = this.load(i);
				if (r != null) {
					sb.append(r.getName()).append(px);
				}
			}
			if (sb.length() > 0) {
				sb.setLength(sb.length() - px.length()); // 去除最后多出来的分隔符
			}
		}
		return sb.toString();
	}

	public String getChildrenIdString(int id, String px) throws Exception {
		String sql = "SELECT id FROM region WHERE parentId=? ORDER BY displayOrder, id";
		List<Integer> childrenIds = this.getEntityIdList(sql, new Object[] { id });
		return StringUtils.join(childrenIds, ",");
	}

	@Override
	public Region getReginById(int id) throws Exception {
		return this.load(id);
	}

	@Override
	public JSONObject toJSON(Region region, String[] keys, String prefix) {
		JSONObject jobj = super.toJSON(region, keys, prefix);
		if (keys == null) {
			keys = new String[] { "leaf" };
		}
		try {
			for (String key : keys) {
				if (key.equals("leaf")) {
					jobj.put(prefix + key, region.isLeaf());
				}
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return jobj;
	}

	// public List<Integer> getFullPath(int id) throws Exception
	// public String getFullPathString(int id) throws Exception
}
